﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MacomberMapSystem.Common.Serialization;
using MacomberMapSystem.Common.Database;
using System.Data.Common;

namespace MacomberMapSystem.Common.User_Interfaces.Database
{
    /// <summary>
    /// This class holds information on a process view
    /// </summary>
    public class ctlProcessView : ListView
    {
        #region Variable declarations
        /// <summary>The data repository associated with the user information</summary>
        private MM_Repository Repository;

        /// <summary>A list of our processes</summary>
        public Dictionary<int, MM_Database_Process> Processes = new Dictionary<int, MM_Database_Process>();

        /// <summary>A list of our processes</summary>
        public Dictionary<int, ListViewItem> ProcessItems = new Dictionary<int, ListViewItem>();     
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize our one-line assignment viewer
        /// </summary>
        public ctlProcessView()
        {
            this.Activation = System.Windows.Forms.ItemActivation.OneClick;
            this.Columns.Add("System");
            this.Columns.Add("User");
            this.Columns.Add("Model");
            this.Columns.Add("Title");
            this.Columns.Add("State");
            this.Columns.Add("Progress");
            this.Columns.Add("Last Update");
            this.FullRowSelect = true;
            this.HideSelection = false;
            this.ShowItemToolTips = true;
        }

        /// <summary>
        /// Initialize our process viewer
        /// </summary>
        /// <param name="Repository"></param>
        public void Initialize(MM_Repository Repository)
        {
            this.Repository = Repository;           
        }
        #endregion

        /// <summary>Update our processes </summary>
        public override void Refresh()
        {
            if (Repository == null)
                return;
            MM_Database_Process Process;
            ListViewItem lvI;
            List<int> IDs = new List<int>();
            using (DbCommand dCmd = Repository.Db.CreateCommand("SELECT * FROM MM_DATABASE_PROCESS"))
            using (DbDataReader dRd = dCmd.ExecuteReader())
                while (dRd.Read())
                {
                    int ThisID = Convert.ToInt32(dRd["ID"]);
                    IDs.Add(ThisID);
                    if (!Processes.TryGetValue(ThisID, out Process) || !ProcessItems.TryGetValue(ThisID, out lvI))
                    {
                        Processes.Add(ThisID, Process = new MM_Database_Process(dRd, Repository));
                        ProcessItems.Add(ThisID, lvI = Items.Add(Process.SystemName));
                            lvI.SubItems.Add(Process.RunBy.FullName);
                        lvI.SubItems.Add(Process.Model == null ? "" : Process.Model.FullClass);
                        lvI.SubItems.Add(Process.ProcessType);
                        lvI.SubItems.Add(Process.State.ToString());
                        lvI.SubItems.Add(Process.CurrentValue + "/" + Process.TotalValue);
                        lvI.SubItems.Add((DateTime.Now - Process.LastUpdate).TotalSeconds.ToString("0") + " sec");
                        
                    }
                    else
                    {
                        Process.Refresh(dRd, Repository);
                        lvI.SubItems[4].Text = Process.State + (Process.Title != null ? ": " + Process.Title : "") ;
                        lvI.SubItems[5].Text = Process.CurrentValue + "/" + Process.TotalValue;
                        lvI.SubItems[6].Text = ((DateTime.Now - Process.LastUpdate).TotalSeconds.ToString("0") + " sec");

                    }
                }

            //Now, remove the ones we don't need
            List<Int32> ToRemove = new List<int>();
            foreach (int ProcessToCheck in Processes.Keys)
                if (!IDs.Contains(ProcessToCheck))
                    ToRemove.Add(ProcessToCheck);

            foreach (Int32 RemoveMe in ToRemove)
            {
                Processes.Remove(RemoveMe);
                Items.Remove(ProcessItems[RemoveMe]);
                ProcessItems.Remove(RemoveMe);
            }
            base.Refresh();
        }

       
    }
}
